10 DEFINT A-Z:DIM B(9,9),BG(9,9),BT(15),BTN(15),MX(9),MY(9),MG(9),ST(81,4)
11 SP=0:SL=0:FOR I=0 TO 14:BT(I)=2^I:BTN(I)=NOT(BT(I)):NEXT I
12 FOR Y=0 TO 8:FOR X=0 TO 8:BG(Y,X)=(Y\3)*3+(X\3):NEXT X:NEXT Y
20 INPUT "Load from file? (Y/N)",F$:IF F$="y" OR F$="Y" THEN GOSUB 300 ELSE GOSUB 320
30 GOSUB 360:PRINT "Calculating...";
40 RN=1:WHILE RN=1 AND SL>0:RN=0:SP0=0
50 FOR SP=0 TO SL-1:X=ST(SP,0):Y=ST(SP,1):G=ST(SP,2)
60 M=NOT(MX(X) OR MY(Y) OR MG(G)) AND &H3FE:IF M=0 THEN PRINT "No answer":END
70 IF (M AND (M-1))<>0 THEN ST(SP0,0)=ST(SP,0):ST(SP0,1)=ST(SP,1):ST(SP0,2)=ST(SP,2):SP0=SP0+1:GOTO 100
80 RN=1:MX(X)=MX(X) OR M:MY(Y)=MY(Y) OR M:MG(G)=MG(G) OR M
90 FOR N=1 TO 9:IF BT(N)=M THEN B(Y,X)=N:GOTO 100
91 NEXT N
100 NEXT SP:SL=SP0:WEND:IF SL=0 THEN PRINT "Complete.":GOSUB 250:END
110 FOR SP=0 TO SL-1:X=ST(SP,0):Y=ST(SP,1):G=ST(SP,2)
120 ST(SP,3)=NOT(MX(X) OR MY(Y) OR MG(G)) AND &H3FE:ST(SP,4)=0
130 NEXT SP:SP=0
140 FOR I=0 TO 9:MX(I)=0:MY(I)=0:MG(I)=0:NEXT I
150 WHILE SP<SL:N=ST(SP,4):X=ST(SP,0):Y=ST(SP,1):G=ST(SP,2)
160 IF N<>0 THEN MG(G)=MG(G) AND BTN(N):MX(X)=MX(X) AND BTN(N):MY(Y)=MY(Y) AND BTN(N)
170 BM=ST(SP,3) AND (NOT(MG(G) OR MX(X) OR MY(Y))) AND &H3FE:GOSUB 220
180 B(Y,X)=N:ST(SP,4)=N:IF N=0 THEN IF SP>0 THEN SP=SP-1:GOTO 210 ELSE PRINT "No answer":END
190 MG(G)=MG(G) OR BT(N):MX(X)=MX(X) OR BT(N):MY(Y)=MY(Y) OR BT(N)
200 SP=SP+1:ST(SP,4)=0
210 WEND:PRINT "Complete.":GOSUB 250:END
220 WHILE N<9:N=N+1:IF (BT(N) AND BM)<>0 THEN RETURN
221 WEND:N=0:RETURN
250 FOR Y=0 TO 8:FOR X=0 TO 8:N=B(Y,X)
251 PRINT USING "# ";B(Y,X);:IF (X MOD 3)=2 THEN PRINT " ";
252 NEXT X:PRINT "":IF (Y MOD 3)=2 THEN PRINT ""
253 NEXT Y:RETURN
300 INPUT "Filename:",F$:OPEN F$ FOR INPUT AS #1:Y=0:WHILE NOT EOF(1)
301 INPUT#1,S$:IF LEN(S$)=9 THEN GOSUB 350:Y=Y+1
302 WEND:CLOSE #1:RETURN
310 INPUT "Filename:",F$:OPEN F$ FOR OUTPUT AS #1:FOR Y=0 TO 8:FOR X=0 TO 7
311 PRINT#1,HEX$(B(Y,X));:NEXT X:PRINT#1,HEX$(B(Y,8)):NEXT Y:CLOSE #1:RETURN
320 PRINT "Input sudoku:":FOR Y=0 TO 8:GOSUB 340:NEXT Y:RETURN
330 INPUT "Which line (1-9)";Y:IF Y<1 OR Y>9 THEN RETURN ELSE Y=Y-1
340 E=1:WHILE E<>0:PRINT Y+1;:INPUT ": ",S$
341 IF LEN(S$)<>9 THEN PRINT "Invalid Input" ELSE E=0
342 WEND
350 FOR X=0 TO 8:B(Y,X)=INSTR(1,"123456789",MID$(S$,X+1,1)):NEXT X:RETURN
360 WHILE 1:CLS:GOSUB 250:GOSUB 400
370 IF E<>0 THEN PRINT "Duplicated number at row";Y+1;", column";X+1
380 INPUT "[C]ompute, [S]ave, [E]dit, [Q]uit: ";K$
381 IF (K$="C" OR K$="c") AND E=0 THEN RETURN
382 IF K$="S" OR K$="s" THEN GOSUB 310
383 IF K$="E" OR K$="e" THEN GOSUB 330
384 IF K$="Q" OR K$="q" THEN PRINT"Quit":END
389 WEND
400 E=0:FOR I=0 TO 9:MX(I)=0:MY(I)=0:MG(I)=0:NEXT I
410 SL=0:FOR Y=0 TO 8:FOR X=0 TO 8:N=B(Y,X):G=BG(Y,X):IF N=0 THEN GOTO 460
420 M=BT(N):DUP=(M AND MX(X))OR(M AND MY(Y))OR(M AND MG(G))
440 IF DUP<>0 THEN E=1:RETURN
450 MX(X)=MX(X) OR M:MY(Y)=MY(Y) OR M:MG(G)=MG(G) OR M:GOTO 490
460 ST(SL,0)=X:ST(SL,1)=Y:ST(SL,2)=G:SL=SL+1
490 NEXT X:NEXT Y:RETURN

